{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 1. 用Pytorch构建两个模型，分别是回归预测和分类预测。要求定义成类的形式。",
   "id": "5a6d218f70016135"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-03T01:59:05.073963Z",
     "start_time": "2025-11-03T01:59:05.065270Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "from torch.utils.data import DataLoader, TensorDataset\n",
    "import numpy as np\n",
    "\n",
    "# 1. 回归模型\n",
    "class RegressionModel(nn.Module):\n",
    "    def __init__(self, input_size):\n",
    "        super(RegressionModel, self).__init__()\n",
    "        self.fc1 = nn.Linear(input_size, 64)\n",
    "        self.fc2 = nn.Linear(64, 32)\n",
    "        self.fc3 = nn.Linear(32, 1)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = torch.relu(self.fc1(x))\n",
    "        x = torch.relu(self.fc2(x))\n",
    "        x = self.fc3(x)\n",
    "        return x.squeeze()\n",
    "\n",
    "# 2. 分类模型\n",
    "class ClassificationModel(nn.Module):\n",
    "    def __init__(self, input_size, num_classes):\n",
    "        super(ClassificationModel, self).__init__()\n",
    "        self.fc1 = nn.Linear(input_size, 64)\n",
    "        self.fc2 = nn.Linear(64, 32)\n",
    "        self.fc3 = nn.Linear(32, num_classes)\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = torch.relu(self.fc1(x))\n",
    "        x = torch.relu(self.fc2(x))\n",
    "        x = self.fc3(x)\n",
    "        return x"
   ],
   "id": "d3db5df99e5a9cc5",
   "outputs": [],
   "execution_count": 5
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# 2. 定义一个train函数，在函数中完成对模型的训练，\n",
    "```\n",
    "def train(model, train_data_loader, epochs):\n",
    "```\n",
    "返回训练好的模型"
   ],
   "id": "332ad388bd79ef1a"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-03T01:59:28.134670Z",
     "start_time": "2025-11-03T01:59:28.124952Z"
    }
   },
   "cell_type": "code",
   "source": [
    "def train(model, train_data_loader, epochs):\n",
    "    criterion = nn.MSELoss() if isinstance(model, RegressionModel) else nn.CrossEntropyLoss()\n",
    "    optimizer = optim.Adam(model.parameters())\n",
    "\n",
    "    model.train()\n",
    "    for epoch in range(epochs):\n",
    "        total_loss = 0\n",
    "        for data, target in train_data_loader:\n",
    "            optimizer.zero_grad()\n",
    "            output = model(data)\n",
    "            loss = criterion(output, target.float() if isinstance(model, RegressionModel) else target)\n",
    "            loss.backward()\n",
    "            optimizer.step()\n",
    "            total_loss += loss.item()\n",
    "\n",
    "        if (epoch + 1) % 10 == 0:\n",
    "            print(f'Epoch [{epoch+1}/{epochs}], Loss: {total_loss/len(train_data_loader):.4f}')\n",
    "\n",
    "    return model"
   ],
   "id": "230dc8d24f5eeb0d",
   "outputs": [],
   "execution_count": 6
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# 3. 定义一个eval函数，在函数中完成对模型的评估，\n",
    "```\n",
    "def eval(model, test_data_loader, eval_metrics):\n",
    "```\n",
    "注意eval_metrics是一个函数，根据不同类型的任务传入不同函数对模型进行评估：\n",
    "- 回归 MSE\n",
    "- 分类 准确率"
   ],
   "id": "900bce31e0405739"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-11-03T02:01:27.932548Z",
     "start_time": "2025-11-03T02:01:23.263862Z"
    }
   },
   "cell_type": "code",
   "source": [
    "def eval(model, test_data_loader, eval_metrics):\n",
    "    model.eval()\n",
    "    predictions, targets = [], []\n",
    "\n",
    "    with torch.no_grad():\n",
    "        for data, target in test_data_loader:\n",
    "            output = model(data)\n",
    "            pred = output.numpy() if isinstance(model, RegressionModel) else torch.argmax(output, 1).numpy()\n",
    "            predictions.extend(pred)\n",
    "            targets.extend(target.numpy())\n",
    "\n",
    "    return eval_metrics(targets, predictions)\n",
    "\n",
    "\n",
    "def mse_metric(y_true, y_pred):\n",
    "    return np.mean((np.array(y_true) - np.array(y_pred)) ** 2)\n",
    "\n",
    "def accuracy_metric(y_true, y_pred):\n",
    "    return np.mean(np.array(y_true) == np.array(y_pred))\n",
    "\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    # 创建数据\n",
    "    X_reg, y_reg = torch.randn(1000, 10), torch.randn(1000)\n",
    "    X_cls, y_cls = torch.randn(1000, 10), torch.randint(0, 3, (1000,))\n",
    "\n",
    "    reg_loader = DataLoader(TensorDataset(X_reg, y_reg), batch_size=32)\n",
    "    cls_loader = DataLoader(TensorDataset(X_cls, y_cls), batch_size=32)\n",
    "\n",
    "    # 创建模型\n",
    "    reg_model = RegressionModel(10)\n",
    "    cls_model = ClassificationModel(10, 3)\n",
    "\n",
    "    print(\"回归模型结构:\")\n",
    "    print(reg_model)\n",
    "    print(\"分类模型结构:\")\n",
    "    print(cls_model)\n",
    "\n",
    "\n",
    "    reg_model = train(reg_model, reg_loader, 30)\n",
    "\n",
    "\n",
    "    cls_model = train(cls_model, cls_loader, 30)\n",
    "\n",
    "    print(f\"\\n回归MSE: {eval(reg_model, reg_loader, mse_metric):.4f}\")\n",
    "    print(f\"分类准确率: {eval(cls_model, cls_loader, accuracy_metric):.4f}\")"
   ],
   "id": "df7b0a476bc09324",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回归模型结构:\n",
      "RegressionModel(\n",
      "  (fc1): Linear(in_features=10, out_features=64, bias=True)\n",
      "  (fc2): Linear(in_features=64, out_features=32, bias=True)\n",
      "  (fc3): Linear(in_features=32, out_features=1, bias=True)\n",
      ")\n",
      "分类模型结构:\n",
      "ClassificationModel(\n",
      "  (fc1): Linear(in_features=10, out_features=64, bias=True)\n",
      "  (fc2): Linear(in_features=64, out_features=32, bias=True)\n",
      "  (fc3): Linear(in_features=32, out_features=3, bias=True)\n",
      ")\n",
      "Epoch [10/30], Loss: 0.9609\n",
      "Epoch [20/30], Loss: 0.8430\n",
      "Epoch [30/30], Loss: 0.7292\n",
      "Epoch [10/30], Loss: 1.0572\n",
      "Epoch [20/30], Loss: 0.9898\n",
      "Epoch [30/30], Loss: 0.9106\n",
      "\n",
      "回归MSE: 0.7018\n",
      "分类准确率: 0.5960\n"
     ]
    }
   ],
   "execution_count": 8
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "f0c942d31a9a9799"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
